﻿using CIS.Common.Dtos.ClientDtos;
using CIS.Common.Entitys;
using CIS.Common.Enums;
using CIS.Server.Common.Responses;
using CIS.Server.Manager.ProcessProgram;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Net;

namespace CIS.Server.Controllers
{
    [Route("[controller]/[action]")]
    [ApiController]
    public class ProcessProgramController : ControllerBase
    {
        private readonly IProcessProgramManager _processProgramManager;

        public ProcessProgramController(IProcessProgramManager processProgramManager)
        {
            _processProgramManager = processProgramManager;
        }

        [HttpGet]
        public async Task<ResponseResult> GetProcessPrograms()
        {
            ResponseResult response = new ResponseResult();
            try
            {
                List<ProcessProgramEntity> programs = await _processProgramManager.GetProcessProgramsAsync();
                
                if (programs != null && programs.Count > 0)
                {
                    List<ProceeProgramClientDto> processPrograms = new List<ProceeProgramClientDto>();
                    foreach (var item in programs)
                    {
                        List<PPIDMappingEntity> ppidMappings = await _processProgramManager.GetPPIDMappingsByPPIDAsync(item.PPID);
                        ProceeProgramClientDto proceeProgramClientDto = new ProceeProgramClientDto();
                        proceeProgramClientDto.PPID = item.PPID;
                        proceeProgramClientDto.OperationName = item.OperationName;
                        proceeProgramClientDto.MixRunFlag = item.MixRunFlag;
                        foreach (var mapping in ppidMappings)
                        {
                            PPIDMappingClientDto mappingEntity = new PPIDMappingClientDto();
                            mappingEntity.PPID = mapping.PPID;
                            mappingEntity.SourceId = mapping.SourceId;
                            mappingEntity.RecipeType = mapping.RecipeType;
                            mappingEntity.RecipeNo = mapping.RecipeNo;
                            proceeProgramClientDto.PPIDRecipeMappingsClient.Add(mappingEntity);
                        }
                        processPrograms.Add(proceeProgramClientDto);
                    }
                    response.IsSuccess = true;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Message = "Operation Is Success";
                    response.Data = processPrograms;
                }
                else
                {
                    response.IsSuccess = false;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Message = "Operation Is Failed Because Can't Find Any Port";
                }
                return response;
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.StatusCode = HttpStatusCode.InternalServerError;
                response.Message = "Operation Is Failed Because Server Is Error";
                return response;
            }
        }

        [HttpPost]
        public async Task<ResponseResult> AddProcessProgram([FromBody] string parameter)
        {
            ResponseResult response = new ResponseResult();
            try
            {
                ProceeProgramClientDto para = JsonConvert.DeserializeObject<ProceeProgramClientDto>(parameter);
                
                if(para != null)
                {
                    ProcessProgramEntity processProgramEntity = await _processProgramManager.GetProcessProgramByPPIDAsync(para.PPID);
                    if (processProgramEntity == null)
                    {
                        ProcessProgramEntity paraEntity = new ProcessProgramEntity();
                        paraEntity.PPID = para.PPID;
                        paraEntity.OperationName = para.OperationName;
                        paraEntity.MixRunFlag = para.MixRunFlag;
                        foreach (var mapping in para.PPIDRecipeMappingsClient)
                        {
                            PPIDMappingEntity mappingEntity = new PPIDMappingEntity();
                            mappingEntity.PPID = para.PPID;
                            mappingEntity.SourceId = mapping.SourceId;
                            mappingEntity.RecipeType = mapping.RecipeType;
                            mappingEntity.RecipeNo = mapping.RecipeNo;
                            paraEntity.PPIDRecipeMappings.Add(mappingEntity);
                        }
                        await _processProgramManager.AddProcessProgramAsync(paraEntity);
                        response.IsSuccess = true;
                        response.StatusCode = HttpStatusCode.OK;
                        response.Message = "Operation Is Success";
                        response.Data = null;
                    }
                    else
                    {
                        response.IsSuccess = false;
                        response.StatusCode = HttpStatusCode.BadRequest;
                        response.Message = "Operation Is Failed There Have The Same PPID Name";
                        response.Data = null;
                    }
                }
                else
                {
                    response.IsSuccess = false;
                    response.StatusCode = HttpStatusCode.BadRequest;
                    response.Message = "Operation Is Failed";
                    response.Data = null;
                }
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.StatusCode = HttpStatusCode.NotFound;
                response.Message = "Operation Is Failed";
                response.Data = null;
            }
            return response;
        }

        [HttpPost]
        public async Task<ResponseResult> DeleteProcessProgram([FromBody] string parameter)
        {
            ResponseResult response = new ResponseResult();
            try
            {
                ProceeProgramClientDto? para = JsonConvert.DeserializeObject<ProceeProgramClientDto>(parameter);
                if (para != null)
                {
                    ProcessProgramEntity entity = await _processProgramManager.GetProcessProgramByPPIDAsync(para.PPID);
                    if (entity != null)
                    {                      
                        await _processProgramManager.DeleteProcessProgramAsync(entity);
                        response.IsSuccess = true;
                        response.StatusCode = HttpStatusCode.OK;
                        response.Message = "Operation Is Success";
                        response.Data = null;
                    }
                    else
                    {
                        response.IsSuccess = false;
                        response.StatusCode = HttpStatusCode.BadRequest;
                        response.Message = "Operation Is Failed Can't Find ProcessProgram";
                        response.Data = null;
                    }
                }
                else
                {
                    response.IsSuccess = false;
                    response.StatusCode = HttpStatusCode.BadRequest;
                    response.Message = "Operation Is Failed";
                    response.Data = null;
                }
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.StatusCode = HttpStatusCode.NotFound;
                response.Message = "Operation Is Failed";
                response.Data = null;
            }
            return response;
        }

        [HttpGet]
        public async Task<ResponseResult> GetRecipes()
        {
            ResponseResult response = new ResponseResult();
            try
            {
                List<RecipeEntity> recipes = await _processProgramManager.GetAllRecipesAsync();

                if (recipes != null && recipes.Count > 0)
                {
                    List<RecipeClientDto> returnRecipes = new List<RecipeClientDto>();
                    foreach (var item in recipes)
                    {
                        RecipeClientDto recipe = new RecipeClientDto();
                        recipe.SourceId = item.SourceId;
                        recipe.RecipeNo = item.RecipeNo;
                        recipe.Version = item.Version;
                        recipe.RecipeType = item.RecipeType;
                        returnRecipes.Add(recipe);
                    }
                    response.IsSuccess = true;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Message = "Operation Is Success";
                    response.Data = returnRecipes;
                }
                else
                {
                    response.IsSuccess = false;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Message = "Operation Is Failed";
                }
                return response;
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.StatusCode = HttpStatusCode.InternalServerError;
                response.Message = "Operation Is Failed Because Server Is Error";
                return response;
            }
        }



    }
}
